package br.com.sgi.util;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.event.ValueChangeEvent;
import javax.servlet.http.HttpServlet;

import org.richfaces.component.html.HtmlCalendar;
import org.richfaces.model.CalendarDataModel;
import org.richfaces.model.CalendarDataModelItem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import br.com.sgi.autentication.UsuarioLogado;
import br.com.sgi.bean.BaseView;
import br.com.sgi.model.Agenda;
import br.com.sgi.model.Igreja;
import br.com.sgi.model.Membro;
import br.com.sgi.service.AgendaService;
import br.com.sgi.service.IgrejaService;
import br.com.sgi.service.MembroService;
import br.com.sgi.service.VisitanteService;
import br.com.sgi.vo.MembroVo;

/**
 * @author Ilya Shaikovsky
 * 
 */
@Controller("calendarDataModel")
@Scope("session")
public class CalendarDataModelImpl extends HttpServlet implements CalendarDataModel {

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.richfaces.component.CalendarDataModel#getData(java.util.Date[])
	 */

	/**
	 * 
	 */
	private static final long serialVersionUID = -2216646221002944808L;

	private String tipoCompromisso;
	private String titulo;
	private Date dtCompromisso;
	private String horaInicio;
	private String horaFim;
	private String descricao;
	private String dataAlterada;
	private String exibirToolTip;
	private String dataCorrente;
	private String opMural;

	private String diaSelecionado;

	private Agenda compromissoSelecionado;

	private Agenda agenda;

	@Autowired
	private AgendaService agendaService;

	@Autowired
	private BaseView baseView;

	private String novoCompromisso;

	private CalendarDataModelItem[] items;

	private HtmlCalendar eventsCalendarControl = new HtmlCalendar();

	private String currentDescription;
	private String currentShortDescription;
	private Date currentDate;

	private boolean currentDisabled;

	private Object data;

	private String dados;
	private String compromisso;

	private final Map<String, List<Agenda>> mapDiaCompromisso = new HashMap<String, List<Agenda>>();

	private List<Agenda> listaCompromisso;
	private List<Igreja> listaIgreja;
	private List<MembroVo> listaMembro;

	@Autowired
	private IgrejaService igrejaService;
	@Autowired
	private MembroService membroService;
	@Autowired
	private VisitanteService visitanteService;

	private String igreja;
	private Igreja igrejaSelecionada;

	/**
	 * adicionar compromisso
	 */
	public void adicionarCompromisso() {
		if (agenda != null) {
			if (agenda.getCoSeqAgenda() == null) {
				listaCompromisso.add(agenda);
			} else {
				for (Agenda ag : listaCompromisso) {
					if (ag.getCoSeqAgenda().equals(agenda.getCoSeqAgenda())) {
						ag.setData(agenda.getData());
						ag.setDescricao(agenda.getDescricao());
						ag.setHoraFim(agenda.getHoraFim());
						ag.setHoraInicio(agenda.getHoraInicio());
						ag.setTipo(agenda.getTipo());
						ag.setTitulo(agenda.getTitulo());
						ag.setIgreja(agenda.getIgreja());
						break;
					}
				}
			}
			agenda = new Agenda();
		}
	}

	public void adicionarIgreja() {
		if (igrejaSelecionada.isSelecionado()) {
			agenda.getIgrejas().add(igrejaSelecionada);
		} else {

			agenda.getIgrejas().remove(igrejaSelecionada);
		}
	}

	public void adicionarIgrejaSelecionada() {
		Igreja igPertence = UsuarioLogado.getIgrejaPertence();
		for (Igreja ig : listaIgreja) {
			if (ig.getCoSeqIgreja().equals(igPertence.getCoSeqIgreja())) {
				ig.setSelecionado(true);
				ig.setDesabilitado(true);
			}
		}
	}

	public List<Igreja> autocomplete(Object suggest) {
		List<Igreja> igrejas = null;
		if (suggest == null) {
			igrejas = new ArrayList<Igreja>();
		} else {
			Membro filtro = new Membro();
			filtro.setNome(suggest.toString().toUpperCase());

			igrejas = igrejaService.buscarIgrejasPorFiltros(suggest.toString().toUpperCase(), null);
		}
		return igrejas;
	}

	/**
	 * inicializa os compromissos a serem exibidos, quando existir
	 */
	private void carregaCompromissoInicarTela() {
		Calendar calendar = Calendar.getInstance();
		if (getCurrentDate() == null) {
			calendar.setTime(new Date());
		} else {
			calendar.setTime(getCurrentDate());
		}

		setCurrentDescription((String) ((HashMap) items[calendar.get(Calendar.DAY_OF_MONTH) - 1]
				.getData()).get("description"));
		setCurrentShortDescription((String) ((HashMap) items[calendar.get(Calendar.DAY_OF_MONTH) - 1]
				.getData()).get("shortDescription"));

		String dia = String.valueOf(calendar.get(Calendar.DAY_OF_MONTH));
		if (dia != null) {
			limparCalendario();
			compromissoSelecionado = null;
			listaCompromisso = mapDiaCompromisso.get(dia);
			if (getCurrentDate() != null) {
				dataCorrente = DateUtil.getDateStr(getCurrentDate());
			}
		}
	}

	/**
	 * carrega compromissos cadastrados
	 */
	public void carregarCompromisso(Date date) {

		Calendar c = Calendar.getInstance();
		c.setTime(date);

		String dia = String.valueOf(c.get(Calendar.DAY_OF_MONTH));
		if (dia != null) {
			compromissoSelecionado = null;
			listaCompromisso = mapDiaCompromisso.get(dia);
		}

	}

	public String carregarDados() {
		baseView.setFoward("agenda");
		if (getCurrentDate() != null) {
			carregarCompromisso(getCurrentDate());
			dataCorrente = DateUtil.getDateStr(getCurrentDate());
		} else {
			carregarCompromisso(new Date());
			dataCorrente = DateUtil.getDateStr(new Date());
		}
		return baseView.getFoward();
	}

	public void carregarIgrejasSelecionadas() {
		setListaIgreja(null);
		for (Igreja ig : getListaIgreja()) {
			for (Igreja igs : agenda.getIgrejas()) {
				if (ig.getCoSeqIgreja().equals(igs.getCoSeqIgreja())) {
					ig.setSelecionado(true);
					break;
				}
			}
		}
	}

	/**
	 * @param date
	 * @return CalendarDataModelItem for date
	 */
	protected CalendarDataModelItem createDataModelItem(Date date) {
		CalendarDataModelItemImpl item = new CalendarDataModelItemImpl();
		Map<String, String> data = new HashMap<String, String>();

		Calendar c = Calendar.getInstance();
		c.setTime(date);
		item.setDay(c.get(Calendar.DAY_OF_MONTH));

		int diaSemana = c.get(Calendar.DAY_OF_MONTH);

		List<Agenda> compromissos = agendaService.buscarAgendasPorMesAno(DateUtil.getDateStr(date));

		if (compromissos != null) {

			mapDiaCompromisso.put(String.valueOf(diaSemana), compromissos);
		}

		item.setEnabled(true);
		if (compromissos != null && compromissos.size() > 0) {
			item.setStyleClass("cellExisteCompromisso");
		} else {
			item.setStyleClass("rel-hol");
		}

		item.setData(data);
		item.setToolTip("");
		return item;
	}

	public Agenda getAgenda() {
		if (agenda == null) {
			agenda = new Agenda();
		}
		return agenda;
	}

	public String getCompromisso() {
		return compromisso;
	}

	public Agenda getCompromissoSelecionado() {
		return compromissoSelecionado;
	}

	/**
	 * @return currentDate
	 */
	public Date getCurrentDate() {
		return currentDate;
	}

	/**
	 * @return currentDescription
	 */
	public String getCurrentDescription() {
		return currentDescription;
	}

	/**
	 * @return currentShortDescription
	 */
	public String getCurrentShortDescription() {
		return currentShortDescription;
	}

	public String getDados() {
		return dados;
	}

	public Object getData() {
		return data;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.richfaces.model.CalendarDataModel#getData(java.util.Date[])
	 */
	public CalendarDataModelItem[] getData(Date[] dateArray) {
		if (dateArray == null) {
			return null;
		}

		// if (items==null) {
		items = new CalendarDataModelItem[dateArray.length];
		for (int i = 0; i < dateArray.length; i++) {
			items[i] = createDataModelItem(dateArray[i]);
		}
		// }
		carregaCompromissoInicarTela();
		return items;
	}

	public String getDataAlterada() {
		return dataAlterada;
	}

	public String getDataCorrente() {

		return dataCorrente;
	}

	public String getDescricao() {
		return descricao;
	}

	public String getDiaSelecionado() {
		return diaSelecionado;
	}

	public Date getDtCompromisso() {
		return dtCompromisso;
	}

	public HtmlCalendar getEventsCalendarControl() {
		return eventsCalendarControl;
	}

	public String getExibirToolTip() {
		return exibirToolTip;
	}

	public String getHoraFim() {
		return horaFim;
	}

	public String getHoraInicio() {
		return horaInicio;
	}

	public String getIgreja() {
		return igreja;
	}

	public Igreja getIgrejaSelecionada() {
		return igrejaSelecionada;
	}

	/**
	 * @return items
	 */
	public CalendarDataModelItem[] getItems() {
		return items;
	}

	public List<Agenda> getListaCompromisso() {
		return listaCompromisso;
	}

	public List<Igreja> getListaIgreja() {
		if (listaIgreja == null) {
			listaIgreja = igrejaService.buscarIgrejasPorUsers();
			adicionarIgrejaSelecionada();
		}

		return listaIgreja;
	}

	public List<MembroVo> getListaMembro() {
		return listaMembro;
	}

	public String getNovoCompromisso() {
		if (novoCompromisso == null) {
			novoCompromisso = "N";
		}
		return novoCompromisso;
	}

	public String getOpMural() {
		return opMural;
	}

	public String getTipoCompromisso() {
		return tipoCompromisso;
	}

	public String getTitulo() {
		return titulo;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.richfaces.model.CalendarDataModel#getToolTip(java.util.Date)
	 */
	public Object getToolTip(Date date) {

		// TODO Auto-generated method stub
		return getCurrentDate();
	}

	/**
	 * @return currentDisabled
	 */
	public boolean isCurrentDisabled() {
		return currentDisabled;
	}

	public void limpar() {
		agenda = new Agenda();
		igreja = "";
		igrejaSelecionada = new Igreja();
		listaIgreja = null;

	}

	private void limparCalendario() {
		listaCompromisso = new ArrayList<Agenda>();
		listaIgreja = null;
		agenda = new Agenda();
		// mapDiaCompromisso = new HashMap<String, List<Agenda>>();
		dataCorrente = null;

	}

	public void limparDadosNoCalendario() {
		limparCalendario();
	}

	private List<MembroVo> obterNiverDia() {
		List<MembroVo> list = membroService.buscarAniversariantesDia(false);
		if (list == null) {
			list = new ArrayList<MembroVo>();
		}

		list.addAll(visitanteService.buscarAniversariantesDia(false));

		return list;
	}

	private List<MembroVo> obterNiverMes() {
		List<MembroVo> list = membroService.buscarAniversariantesMes(false);
		if (list == null) {
			list = new ArrayList<MembroVo>();
		}

		list.addAll(visitanteService.buscarAniversariantesMes(false));

		return list;
	}

	/**
	 * carregas compromissos da data corrente
	 */
	public void recarregarCalendario() {
		items = null;

	}

	/**
	 * remove compromisso
	 */
	public void removerCompromisso() {
		if (compromissoSelecionado != null) {
			if (compromissoSelecionado != null) {
				agendaService.excluir(compromissoSelecionado.getCoSeqAgenda());
				createDataModelItem(getCurrentDate());
				carregarCompromisso(getCurrentDate());
				//listaCompromisso = new ArrayList<Agenda>();
			}
			Mensagem.infoMsg("sucesso.MSG_01");
		}
	}

	public void removerIgreja() {
		agenda.getIgrejas().remove(igrejaSelecionada);
	}

	/**
	 * Salva compromisso
	 */
	public void salvarCompromisso() {

		// if (getCurrentDate() == null) {

		// } else {
		if (getCurrentDate() == null) {
			setCurrentDate(new Date());
		}

		storeDayDetails();

		Date dataSelecionada = getCurrentDate();

		if (agenda.getCoSeqAgenda() == null) {
			agenda.setData(dataSelecionada);
			agenda.setIgreja(UsuarioLogado.getIgrejaPertence());
			// agenda.setIgrejas(listaIgreja);
			agendaService.salvar(agenda);
			limpar();
			Mensagem.infoMsg("sucesso.MGS_02");
		} else {
			agendaService.update(agenda);
			limpar();
			Mensagem.infoMsg("sucesso.MGS_03");
		}

		createDataModelItem(dataSelecionada);

		carregarCompromisso(dataSelecionada);
		limpar();
		// }
	}

	public void setAgenda(Agenda agenda) {
		this.agenda = agenda;
	}

	public void setCompromisso(String compromisso) {
		this.compromisso = compromisso;
	}

	public void setCompromissoSelecionado(Agenda compromissoSelecionado) {
		this.compromissoSelecionado = compromissoSelecionado;
	}

	/**
	 * @param currentDate
	 */
	public void setCurrentDate(Date currentDate) {
		this.currentDate = currentDate;
	}

	/**
	 * @param currentDescription
	 */
	public void setCurrentDescription(String currentDescription) {
		this.currentDescription = currentDescription;
	}

	/**
	 * @param currentDisabled
	 */
	public void setCurrentDisabled(boolean currentDisabled) {
		this.currentDisabled = currentDisabled;
	}

	/**
	 * @param currentShortDescription
	 */
	public void setCurrentShortDescription(String currentShortDescription) {
		this.currentShortDescription = currentShortDescription;
	}

	public void setDados(String dados) {
		this.dados = dados;
	}

	public void setData(Object data) {
		this.data = data;
	}

	public void setDataAlterada(String dataAlterada) {
		this.dataAlterada = dataAlterada;
	}

	public void setDataCorrente(String dataCorrente) {
		this.dataCorrente = dataCorrente;
	}

	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}

	public void setDiaSelecionado(String diaSelecionado) {
		this.diaSelecionado = diaSelecionado;
	}

	public void setDtCompromisso(Date dtCompromisso) {
		this.dtCompromisso = dtCompromisso;
	}

	public void setEventsCalendarControl(HtmlCalendar eventsCalendarControl) {
		this.eventsCalendarControl = eventsCalendarControl;
	}

	public void setExibirToolTip(String exibirToolTip) {
		this.exibirToolTip = exibirToolTip;
	}

	public void setHoraFim(String horaFim) {
		this.horaFim = horaFim;
	}

	public void setHoraInicio(String horaInicio) {
		this.horaInicio = horaInicio;
	}

	public void setIgreja(String igreja) {
		this.igreja = igreja;
	}

	public void setIgrejaSelecionada(Igreja igrejaSelecionada) {
		this.igrejaSelecionada = igrejaSelecionada;
	}

	/**
	 * @param setter
	 *            for items
	 */
	public void setItems(CalendarDataModelItem[] items) {
		this.items = items;
	}

	public void setListaCompromisso(List<Agenda> listaCompromisso) {
		this.listaCompromisso = listaCompromisso;
	}

	public void setListaIgreja(List<Igreja> listaIgreja) {
		this.listaIgreja = listaIgreja;
	}

	public void setListaMembro(List<MembroVo> listaMembro) {
		this.listaMembro = listaMembro;
	}

	public void setNovoCompromisso(String novoCompromisso) {
		this.novoCompromisso = novoCompromisso;
	}

	public void setOpMural(String opMural) {
		this.opMural = opMural;
	}

	public void setTipoCompromisso(String tipoCompromisso) {
		this.tipoCompromisso = tipoCompromisso;
	}

	public void setTitulo(String titulo) {
		this.titulo = titulo;
	}

	/**
	 * Storing changes action
	 */
	public void storeDayDetails() {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(getCurrentDate());
		((HashMap) items[calendar.get(Calendar.DAY_OF_MONTH) - 1].getData()).put(
				"shortDescription", getCurrentShortDescription());
		((HashMap) items[calendar.get(Calendar.DAY_OF_MONTH) - 1].getData()).put("description",
				getCurrentDescription());
		((HashMap) items[calendar.get(Calendar.DAY_OF_MONTH) - 1].getData()).put("dateCurrent",
				Calendar.DAY_OF_MONTH);

	}

	/**
	 * @param valueChangeEvent
	 *            handling
	 */
	public void valueChanged(ValueChangeEvent event) {
		if (event.getNewValue() != null) {
			System.out.println(event.getNewValue() + "selected");
			setCurrentDate((Date) event.getNewValue());
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(getCurrentDate());
			setCurrentDescription((String) ((HashMap) items[calendar.get(Calendar.DAY_OF_MONTH) - 1]
					.getData()).get("description"));
			setCurrentShortDescription((String) ((HashMap) items[calendar
					.get(Calendar.DAY_OF_MONTH) - 1].getData()).get("shortDescription"));

			String dia = String.valueOf(calendar.get(Calendar.DAY_OF_MONTH));
			if (dia != null) {
				limparCalendario();
				compromissoSelecionado = null;
				listaCompromisso = mapDiaCompromisso.get(dia);
				if (getCurrentDate() != null) {
					dataCorrente = DateUtil.getDateStr(getCurrentDate());
				}
			}
		}
	}

	public void verTudo() {
		listaCompromisso = new ArrayList<Agenda>();
		listaMembro = new ArrayList<MembroVo>();
		if (opMural != null) {

			if (opMural.equals("niverMes")) {
				listaMembro = obterNiverMes();
			} else if (opMural.equals("niverDia")) {
				listaMembro = obterNiverDia();
			} else if (opMural.equals("agendaMes")) {
				listaCompromisso = agendaService.buscarAgendaDoMes();
			} else if (opMural.equals("agendaDia")) {
				listaCompromisso = agendaService.buscarAgendaDoDia();
			}

			opMural = "";
		}
	}

	public String voltar() {
		baseView.setFoward("home");
		limparCalendario();
		carregaCompromissoInicarTela();
		return baseView.getFoward();

	}

}